package controllers;

import javax.servlet.http.HttpServletRequest;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import dao.UserDAO;
import utils.GenericValidationAndOptions;
import models.game.Game;
import models.players.Player;

@Controller
public class DispatchController {

	ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
	UserDAO userDao = (UserDAO) context.getBean("userDao");

	@RequestMapping("/RedirectPlayers")
	public synchronized String redirectPlayers(HttpServletRequest request) {

		Game game = (Game) request.getSession().getAttribute("game");

		// Checks if the game is lost
		if (game.getGameIsLost() == true) {

			// Increases the losses of the player in the database
			userDao.increaseLosses(game);
			// Removes the player from the list with active players
			removePlayersFromActive(game);
			// Redirects to the LooserPage.jsp
			return "LooserPage";
		}

		// Checks if the game is won
		if (((Game) request.getSession().getAttribute("game")).getGameIsWon() == true) {

			// Increases the wins of the player in the database
			userDao.increaseWins(game);
			// Removes the player form the list with active players
			removePlayersFromActive(game);
			// Redirects to the WinnerPage.jsp
			return "WinnerPage";
		}

		// if this code is reached the player is in a ongoing game therefore is
		// redirected to the MapHandler to update the Map.jsp for him
		return "redirect:/MapHandler";

	}

	// After the map is updated redirects the player to the active or inactive
	// page, depending on the turn
	@RequestMapping("/ContinuingGameRedirect")
	public synchronized String redirectPlayersInOngoingGame(
			HttpServletRequest request) {

		Game game = (Game) request.getSession().getAttribute("game");
		Player player = (Player) request.getSession().getAttribute("player");

		if (player.getTurnIndex() == game.getActiveTurn()) {
			
			// Calls a method that checks if an action should be available to a
			// player and adds a boolean attribute for each one in the player
			// session
			verifyAllActions(request, player, game);
			
			return "ActivePage";
		} else {
			return "InactivePage";
		}
	}

	// A method that checks if an action should be available to a
	// player and adds a boolean attribute for each one in the player
	// session
	public synchronized void verifyAllActions(HttpServletRequest request,
			Player player, Game game) {
		request.getSession().setAttribute("canDrive", canDrive(player, game));
		request.getSession().setAttribute("canDirectFlight",
				canDirectFlight(player, game));
		request.getSession().setAttribute("canCharterFlight",
				canCharterFlight(player, game));
		request.getSession().setAttribute("canShuttleFlight",
				canShuttleFlight(player, game));
		request.getSession().setAttribute("canBuildReserachStation",
				canBuildReserachStation(player, game));
		request.getSession().setAttribute("canTreatDisease",
				canTreatDisease(player, game));
		request.getSession().setAttribute("canDiscoverACure",
				canDiscoverACure(player, game));
		request.getSession().setAttribute("canRecieveKnowledge",
				canRecieveKnowledge(player, game));
		request.getSession().setAttribute("canShareKnowledge",
				canShareKnowledge(player, game));
	}

	//A method that removes the inactive players from the active players list
	private void removePlayersFromActive(Game game) {
		for (Player p : game.getPlayers().values()) {
			if (GameMenuController.getActivePlayers().containsValue(p)) {
				GameMenuController.getActivePlayers().remove(p.getSessionId());
			}
		}
	}
	
	// Now unnecessary and repetitive, to be refactored once roles are implemented
	public static boolean canDrive(Player player, Game game) {
		return GenericValidationAndOptions.canDrive(player, game);
	}

	private static boolean canDirectFlight(Player player, Game game) {
		return GenericValidationAndOptions.canDirectFlight(player, game);
	}

	public static boolean canCharterFlight(Player player, Game game) {
		return GenericValidationAndOptions.canCharterFlight(player, game);
	}

	public static boolean canShuttleFlight(Player player, Game game) {
		return GenericValidationAndOptions.canShuttleFlight(player, game);
	}

	public static boolean canBuildReserachStation(Player player, Game game) {
		return GenericValidationAndOptions
				.canBuildReserachStation(player, game);
	}

	public static boolean canTreatDisease(Player player, Game game) {
		return GenericValidationAndOptions.canTreatDisease(player, game);
	}

	public static boolean canDiscoverACure(Player player, Game game) {
		return GenericValidationAndOptions.canDiscoverACure(player, game);
	}

	public static boolean canRecieveKnowledge(Player player, Game game) {
		return GenericValidationAndOptions.canRecieveKnowledge(player, game);
	}

	public static boolean canShareKnowledge(Player player, Game game) {
		return GenericValidationAndOptions.canShareKnowledge(player, game);
	}

}
